package kr.co.insoft.core.repository.orchestration.impl;

import java.util.List;

import kr.co.insoft.core.mapper.orchestration.OrchestrationMapper;
import kr.co.insoft.core.model.orchestration.CompositeEntityModel;
import kr.co.insoft.core.model.orchestration.CompositeStackEntityModel;
import kr.co.insoft.core.model.orchestration.OrchestrationResultModel;
import kr.co.insoft.core.model.orchestration.ProjectEntityModel;
import kr.co.insoft.core.model.orchestration.ServiceEntityModel;
import kr.co.insoft.core.repository.orchestration.OrchestrationRepository;
import kr.co.insoft.framework.exceptions.ExceptionCode;
import kr.co.insoft.framework.exceptions.RepositoryException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

@Repository
public class OrchestrationRepositoryImpl implements OrchestrationRepository {

	private static final Logger OrchestrationRepositoryImplLog = LoggerFactory
			.getLogger(OrchestrationRepositoryImpl.class);

	@Autowired
	OrchestrationMapper orchestrationMapper;

	@Override
	public OrchestrationResultModel createProject(
			ProjectEntityModel projectEntityModel) throws RepositoryException {
		try {
			Assert.notNull(projectEntityModel);
			Assert.notNull(projectEntityModel.getProjectName());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel.getProjectName());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			String uuid = orchestrationMapper.getUuid();
			projectEntityModel.setProjectid(uuid);
			orchestrationMapper.createProject(projectEntityModel);
			return new OrchestrationResultModel("project", uuid, true);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public ProjectEntityModel getProject(ProjectEntityModel projectEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(projectEntityModel);
			Assert.notNull(projectEntityModel.getProjectid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel.getProjectid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper.getProject(projectEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public OrchestrationResultModel createService(
			ServiceEntityModel serviceEntityModel) throws RepositoryException {
		try {
			Assert.notNull(serviceEntityModel);
			Assert.notNull(serviceEntityModel.getProjectid());
			Assert.notNull(serviceEntityModel.getServiceName());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel.getProjectid());
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel.getServiceName());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			String uuid = orchestrationMapper.getUuid();
			serviceEntityModel.setServiceid(uuid);
			orchestrationMapper.createService(serviceEntityModel);
			return new OrchestrationResultModel("service", uuid, true);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public ServiceEntityModel getService(ServiceEntityModel serviceEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(serviceEntityModel);
			Assert.notNull(serviceEntityModel.getServiceid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel.getServiceid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper.getService(serviceEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public OrchestrationResultModel createComposite(
			CompositeEntityModel compositeEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(compositeEntityModel);
			Assert.notNull(compositeEntityModel.getServiceid());
			Assert.notNull(compositeEntityModel.getCompositeName());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel.getServiceid());
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel.getCompositeName());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			String uuid = orchestrationMapper.getUuid();
			compositeEntityModel.setCompositeid(uuid);
			orchestrationMapper.createComposite(compositeEntityModel);
			return new OrchestrationResultModel("vmcomposite", uuid, true);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public CompositeEntityModel getComposite(
			CompositeEntityModel compositeEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(compositeEntityModel);
			Assert.notNull(compositeEntityModel.getCompositeid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel.getCompositeid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper.getComposite(compositeEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	public int getProjectChildCount(ProjectEntityModel projectEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(projectEntityModel);
			Assert.notNull(projectEntityModel.getProjectid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel.getProjectid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper.getChildCountProject(projectEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public void removeProject(ProjectEntityModel projectEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(projectEntityModel);
			Assert.notNull(projectEntityModel.getProjectid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel.getProjectid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			orchestrationMapper.removeProject(projectEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public int getChildCountComposite(CompositeEntityModel compositeEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(compositeEntityModel);
			Assert.notNull(compositeEntityModel.getCompositeid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel.getCompositeid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper
					.getChildCountComposite(compositeEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public int getChildCountService(ServiceEntityModel serviceEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(serviceEntityModel);
			Assert.notNull(serviceEntityModel.getServiceid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel.getServiceid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper.getChildCountService(serviceEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public void removeComposite(CompositeEntityModel compositeEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(compositeEntityModel);
			Assert.notNull(compositeEntityModel.getCompositeid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel.getCompositeid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			orchestrationMapper.removeComposite(compositeEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public void removeService(ServiceEntityModel serviceEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(serviceEntityModel);
			Assert.notNull(serviceEntityModel.getProjectid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel.getProjectid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			orchestrationMapper.removeService(serviceEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public List<ProjectEntityModel> getProjectsForSearchCondition(
			ProjectEntityModel projectEntityModel) throws RepositoryException {
		try {
			Assert.notNull(projectEntityModel);
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					projectEntityModel);
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper
					.getProjectsForSearchCondition(projectEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public List<ServiceEntityModel> getServicesForSearchCondition(
			ServiceEntityModel serviceEntityModel) throws RepositoryException {
		try {
			Assert.notNull(serviceEntityModel);
			Assert.notNull(serviceEntityModel.getProjectid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					serviceEntityModel.getProjectid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper
					.getServicesForSearchCondition(serviceEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public List<CompositeEntityModel> getCompositesForSearchCondition(
			CompositeEntityModel compositeEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(compositeEntityModel);
			Assert.notNull(compositeEntityModel.getServiceid());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeEntityModel.getServiceid());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			return orchestrationMapper
					.getCompositesForSearchCondition(compositeEntityModel);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}

	@Override
	public OrchestrationResultModel createStack(
			CompositeStackEntityModel compositeStackEntityModel)
			throws RepositoryException {
		try {
			Assert.notNull(compositeStackEntityModel);
			Assert.notNull(compositeStackEntityModel.getConnectionid());
			Assert.notNull(compositeStackEntityModel.getHardwareProfileId());
		} catch (IllegalArgumentException e) {
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeStackEntityModel);
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeStackEntityModel.getConnectionid());
			OrchestrationRepositoryImplLog.error(ExceptionCode.ASSERT_FORMAT,
					compositeStackEntityModel.getHardwareProfileId());
			throw new RepositoryException(ExceptionCode.ARGUMENT_ERROR);
		}

		try {
			String uuid = orchestrationMapper.getUuid();
			compositeStackEntityModel.setStackid(uuid);
			orchestrationMapper.createStack(compositeStackEntityModel);
			return new OrchestrationResultModel("vmcompositestack", uuid, true);
		} catch (Exception e) {
			throw new RepositoryException(ExceptionCode.REPOSITORY_EXCEPTION, e);
		}
	}
}
